home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 211_01 / xsrchr.c < prev    next >
C/C++ Source or Header  |  1980-01-01  |  22KB  |  1,076 lines

  1. /*XSRCHR.C    VERS:- 01.00  DATE:- 09/26/86  TIME:- 09:38:02 PM */
  2. /*
  3. %CC1 $1.C -O -X -E7A00
  4. %CLINK $1 SCOPE DIO WILDEXP -F CHARFUN STRFUN -S -E7A00
  5. %DELETE $1.CRL 
  6. */
  7. /* 
  8. Description:
  9.  
  10. Search over each record of each file in wildcard filelist; 
  11. if the seach pattern is found in a record, display it, 
  12. with DIO output redirection.
  13.  
  14. If the search pattern is given as the first command line parameter,
  15. the record delimiter is assumed to be '\n'.
  16.  
  17. If the -p option is selected or the search pattern is not given on the
  18. command line, there is full screen input of:
  19.     search patterns;
  20.     record delimiter;
  21.     output delimiters;
  22.     cas_flag;
  23.  
  24. In the case of full screen input, there can be up to 10 search patterns, 
  25. which may be or'd, and'd, or not'd.
  26.  
  27. If the cas_flag is set, the file name is printed at the start of
  28. the first line of output of each record.
  29.  
  30. Strings can include meta characters, such as '*', '?', etc.  
  31. See help_mess for a listing of them.
  32.  
  33.  
  34. Usage:
  35.  
  36. xsrch   [pattern]   input   [>output_ufn (def = crt)]   [-options (-h = help)] 
  37.  
  38. The input parameter is required.  It can be either:
  39.     input_afn1 [input_anf2, ..]   and/or   <input_ufn_list
  40.         
  41. If a pattern to be searched for is given on the command line (rather than
  42. given through full-screen input), it must precede the input parameter.
  43.  
  44. It is best to select full screen input with the option '-p', rather than
  45. trust to default selection.
  46.  
  47. See help_mess for more information on options.
  48.  
  49.  
  50. From public domain code: 
  51.     Van Nuys SEARCH, DIO, WILDEXP (by Eugene H. Mallory):
  52.         WILDEXP modified to allow du: == u/d:.
  53.         DIO modified to avoid cr-cr-lf triple with putchar.
  54.         some functions rewritten from code in SEARCH:
  55.             decode()
  56.             find()
  57.             search()
  58.     CUG SCOPE:
  59.         Full screen input based on the template file XSRCH.ZIP:
  60.             select  and, not, or   strings;
  61.             select parts of record for output;
  62.                 select record delimiter;
  63.             select flags.
  64.  
  65.  
  66. Depending on test, 1-5 x slower than FIND.COM.
  67.  
  68. Effects on efficiency:
  69. major    use of machine coded routines for character and string operations;
  70. major    use of file read() with large block size;
  71. major    inline C-code for touppper in search();
  72. minor    reduced parameter passing;
  73. minor    reduced setting of variables; 
  74. minor    use of ! instead of  == 0;
  75. minor    return from recursive calls of search with longjmp;
  76. minor    expand code of search(), so branching gives fewer operations/branch;
  77. minor    pointer arithmetic instead of arrays in search().
  78.  
  79.  
  80. By J.A. Rupley, Tucson, Arizona
  81. Coded for BDS C compiler, version 1.50a
  82. */
  83.  
  84. /* page eject */
  85. #include "bdscio.h"
  86. #include "dio.h"
  87.  
  88. /*configuration*/
  89. #define READSECS 10
  90. #define BUFLEN (((6 * READSECS) + 1) * 128)
  91. #define DELIM "\n"
  92. #define NO_SUMMARY FALSE
  93. #define LIST_FLAG TRUE
  94. #define RECORD_NUMBERS FALSE
  95. #define INP_PATTERN FALSE
  96. #define DISP_CTRL FALSE
  97. #define SKIP 0
  98. #define CAS_FLAG FALSE
  99.  
  100. /*search constants*/
  101. #define FOUND 0x80
  102. #define NOTFOUND 0x81
  103. #define MATCH 0x82
  104. #define NOTMATCH 0x83
  105. #define NOTBEGIN 0xff
  106. #define NOTEND 0x9d
  107. #define SKIPANY 0x86
  108. #define SKIPONE 0x87
  109. #define IGNOREONE 0x1c
  110. #define LINEEND 0x1d
  111. #define LINESTART 0x7f
  112. #define ANYALPHA 0x1e
  113. #define ANYNUMBER 0x1f
  114.  
  115. /*buffers and arrays*/
  116. #define NPAT 10
  117. #define NDRIVER 7
  118. #define NOUT 10
  119.  
  120. char string[BUFLEN];
  121. char pat_buf[42];
  122. char delim[42];
  123. char pat_array[NPAT][42];
  124. char out_start[NOUT][21];
  125. char out_end[NOUT][21];
  126. char fname[MAXLINE];
  127. char jbuf[JBUFSIZE];
  128.  
  129. /*external constants, used for speed or control*/
  130. int i, j, firstpat, nextpat;
  131. int skip, no_summary, list_flag, record_numbers;
  132. int disp_ctrl, inp_pattern, optionerr;
  133. int cas_flag;
  134. int npat, nout;
  135. char *pattern;
  136. int ioblks, iofile;
  137.  
  138. main(argc, argv)
  139. char **argv;
  140. int argc;
  141. {
  142.     int ii;
  143.     int string_compare();
  144.  
  145.     cas_flag = CAS_FLAG;
  146.     inp_pattern = INP_PATTERN;
  147.     record_numbers = RECORD_NUMBERS;
  148.     no_summary = NO_SUMMARY;
  149.     list_flag = LIST_FLAG;
  150.     optionerr = FALSE;
  151.     disp_ctrl = DISP_CTRL;
  152.     skip = SKIP;
  153.  
  154.     dioinit(&argc, argv);
  155.  
  156.     get_options(&argc, argv);
  157.  
  158.     if (optionerr || ((argc < 2) && !DIOIN))
  159.         help_mess();
  160.  
  161.     /*set up patterns, of all sorts*/
  162.  
  163.     if (((argc < 3) && !DIOIN) || inp_pattern)
  164.     {
  165.         inp_pattern = TRUE;
  166.         full_screen();
  167.     }
  168.     else
  169.     {
  170.         strcpy(delim, DELIM);
  171.  
  172.         pat_decode(argv[1], &pat_array[0][1]);
  173.         pat_array[0][0] = 'O';
  174.         npat = 1;
  175.         argv = &argv[1];
  176.         argc -= 1;
  177.     }
  178.  
  179.     /* now wildcard and sort what is left on command line */
  180.  
  181.     wildexp(&argc, &argv);
  182.     qsort(&argv[1], argc - 1, 2, &string_compare);
  183.  
  184.     /* search filelist from command line, if any*/
  185.  
  186.     for (ii = 1; ii < argc; ii++)
  187.     {
  188.         strcpy(fname, argv[ii]);
  189.         find_all(fname);
  190.     }
  191.  
  192.     /* search filelist from input file, if any*/
  193.  
  194.     if (DIOIN)
  195.         while (!getstring(fname))
  196.             find_all(fname);
  197.  
  198.     dioflush();
  199.     exit();
  200. }
  201. /* END OF MAIN*/
  202.  
  203. /*page eject*/
  204.  
  205. int find_all(fname)
  206. char *fname;
  207. {
  208.     int c, temp;
  209.     int record;
  210.     int next, isave;
  211.     char csave, csavefirst;
  212.     char ichar;
  213.     int find_count;
  214.     int jj, kk;
  215.     int first_char, end_char;
  216.     int first_temp, end_temp;
  217.  
  218.     /*fill after end of file name with spaces to column 20*/
  219.     /*then open file, print filename, and process file*/
  220.     
  221.     for (jj = strlen(fname); jj; jj--)
  222.         if ((c = fname[jj - 1]) != ' ' && c != '\r' && c != '\n')
  223.             break;
  224.     while (jj < 20)
  225.         fname[jj++] = ' ';
  226.     fname[jj] = '\0';
  227.  
  228.     if ((iofile = open(fname, 0)) == ERROR)
  229.     {
  230.         typef("\nFIND_ALL: cannot open file %s.\n", fname);
  231.         close(iofile);
  232.         return (0);
  233.     }
  234.     else
  235.         if (!no_summary)
  236.             printf("\f\n%s\n", fname);
  237.  
  238.     find_count = 0;
  239.     record = 1;
  240.     string[0] = LINESTART;
  241.     string[1] = '\0';
  242.  
  243.     if (skip)
  244.         if ((record += skip_lines(skip)) == ERROR)
  245.         {
  246.             typef(" %s.\n", fname);
  247.             close(iofile);
  248.             return (0);
  249.         }
  250.  
  251.     firstpat = 0;
  252.  
  253.     /*main loop to search file for pattern, record by record*/
  254.     /*first, with -pat_gets- find next record terminated by -delim- */
  255.  
  256.     while ((temp = pat_gets(delim)) != ERROR)
  257.     {
  258.  
  259.         /*intercept console input*/
  260.  
  261.         if (bdos(11))
  262.         {
  263.             if ((c = bdos(1)) == 0x03)        /*ctrl-c*/
  264.             {
  265.                 typef("\nFIND_ALL: Control C intercepted\n");
  266.                 dioexit();
  267.             }
  268.             else
  269.                 if (c == 0x18)        /*ctrl-x*/
  270.             {
  271.                 typef("\nFIND_ALL: Control X intercepted\n");
  272.                 close(iofile);
  273.                 return (1);
  274.             }
  275.         }
  276.  
  277.         /*store end characters of record */
  278.         /*replace by special delimiters for search*/
  279.  
  280.         csavefirst = string[firstpat];
  281.         string[firstpat] = LINEEND;
  282.         isave = firstpat + 1;
  283.         csave = string[isave];
  284.         string[isave] = '\0';
  285.         next = nextpat;
  286.  
  287.         /*with -all_pats- search record for all patterns*/
  288.         /*output as appropriate*/
  289.  
  290.         if (all_pats() == FOUND)
  291.         {
  292.  
  293.             if (!find_count++)
  294.             {
  295.                 outs(delim, MAXLINE, disp_ctrl);
  296.                 printf("\n");
  297.             }
  298.  
  299.             if (list_flag)
  300.             {
  301.                 if (nout)
  302.                 {
  303.                     if (cas_flag)
  304.                         printf("%s", fname);
  305.  
  306.                     if (record_numbers)
  307.                         printf("Record number %-7d ", record);
  308.  
  309.                     first_char = 1;
  310.  
  311.                     for (kk = 0; kk < nout; kk++)
  312.                     {
  313.                         firstpat = first_char;
  314.                         pattern = out_start[kk];
  315.  
  316.                         if (find() != FOUND)
  317.                             continue;
  318.  
  319.                         first_char = firstpat++;
  320.                         pattern = out_end[kk];
  321.  
  322.                         if (find() != FOUND)
  323.                             continue;
  324.  
  325.                         end_char = firstpat;
  326.  
  327.                         outs(&string[first_char], (end_char - first_char), disp_ctrl);
  328.  
  329.                         if (temp == FOUND && kk == (nout - 1))
  330.                             for (jj = 0; (ichar = out_end[kk][jj]); jj++)
  331.                                 if (ichar == LINEEND && (out_end[kk][jj - 1] != '!'))
  332.                                     outs(delim, MAXLINE, disp_ctrl);
  333.                     }
  334.                 }
  335.                 else
  336.                 {
  337.                     if (record_numbers)
  338.                         printf("%7d ", record);
  339.  
  340.                     string[isave - 1] = '\0';
  341.  
  342.                     outs(&string[1], BUFLEN, disp_ctrl);
  343.  
  344.                     if (temp == FOUND)
  345.                         outs(delim, BUFLEN, disp_ctrl);
  346.                 }
  347.             }
  348.  
  349.             /*if not list_flag, ie if select files, not lines*/
  350.  
  351.             else
  352.             {
  353.                 if (!no_summary)
  354.                     summary_output(find_count);
  355.  
  356.                 close(iofile);
  357.                 return (1);
  358.             }
  359.         }
  360.  
  361.         record++;
  362.  
  363.         /*normal exit at end of file*/
  364.  
  365.         if (temp == NOTFOUND)
  366.         {
  367.             outs(delim, MAXLINE, disp_ctrl);
  368.             printf("\n");
  369.  
  370.             if (!no_summary)
  371.             {
  372.                 if